﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ScrewTurn.Wiki.PluginFramework;
using System.Web.UI;
using ScrewTurn.Wiki;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;

namespace Stankovski.Wiki.DiscussionTag
{
	public class DiscussionTag : IFormatterProviderV30
	{
		protected IHostV30 host;
		protected string config;
		private Regex discussion = new Regex("{discussion}", RegexOptions.Compiled | RegexOptions.IgnoreCase);
		private Regex configPattern = new Regex(@"AllowEditing\s?=\s?(?<val>True|False)");

		public bool PerformPhase1
		{
			get { return false; }
		}

		public bool PerformPhase2
		{
			get { return false; }
		}

		public bool PerformPhase3
		{
			get { return true; }
		}

		public int ExecutionPriority
		{
			get { return 50; }
		}

		public string Format(string raw, ContextInformation context, FormattingPhase phase)
		{
			bool configAllowEditing = false;
			bool canViewDiscussion = true;
			bool canPostDiscussion = false;
			bool canManageDiscussion = false;

			if (config != null && configPattern.IsMatch(config))
			{
				string val = configPattern.Match(config).Groups["val"].Value;
				if (val != null && val.Trim().ToLower() == "true")
					configAllowEditing = true;
			}


			if (discussion.IsMatch(raw) && phase == FormattingPhase.Phase3 && context.Context != FormattingContext.MessageBody)
			{
				canViewDiscussion = host.CheckActionForPage(context.Page, Actions.ForPages.ReadDiscussion, host.GetCurrentUser());
				canPostDiscussion = host.CheckActionForPage(context.Page, Actions.ForPages.PostDiscussion, host.GetCurrentUser());
				canManageDiscussion = host.CheckActionForPage(context.Page, Actions.ForPages.ManageDiscussion, host.GetCurrentUser());

				if (!configAllowEditing)
				{
					canPostDiscussion = false;
					canManageDiscussion = false;
				}

				if (canViewDiscussion)
					return discussion.Replace(raw, renderPageDiscussion(context, canPostDiscussion, canManageDiscussion));
				else
					return discussion.Replace(raw, "");
			}
			else
			{
				return raw;
			}
		}

		private string renderPageDiscussion(ContextInformation context, bool canPostDiscussion, bool canManageDiscussion)
		{
			try
			{
				Page pageHolder = new Page();
				PageDiscussion discussion = pageHolder.LoadControl("~/PageDiscussion.ascx") as PageDiscussion;
				discussion.CurrentPage = context.Page;
				discussion.CanPostMessages = canPostDiscussion;
				discussion.CanManageDiscussion = canManageDiscussion;

				pageHolder.Controls.Add(discussion);
				StringWriter output = new StringWriter();
				HttpContext.Current.Server.Execute(pageHolder, output, false);
				return output.ToString();
			}
			catch (Exception ex)
			{
				return "Failed to render message board.";
			}
		}

		public string PrepareTitle(string title, ContextInformation context)
		{
			return title;
		}

		public void Init(IHostV30 host, string config)
		{
			this.host = host;
			this.config = config;
		}

		public void Shutdown()
		{
			// DO NOTHING
		}

		public ComponentInformation Information
		{
			get
			{
				return new ComponentInformation(this.GetType().Name, "Denis Stankovski", "1.0", null, null);
			}
		}

		public string ConfigHelpHtml
		{
			get { return "AllowEditing=True|False"; }
		}
	}
}
